home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Eudora 1.3.1 / source / uupc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  15.4 KB  |  613 lines  |  [TEXT/MPS ]

  1. #define FILE_NUM 47
  2. #pragma load EUDORA_LOAD
  3. Boolean SkipToFromLine(void);
  4.  
  5. /************************************************************************
  6.  * Incoming from UUPC
  7.  *    - We put the pathname in the POP account, preceeded by a !.
  8.  *    - Then, it's just a matter of sicking POPMessageBody on each message.
  9.  *    --- Well, we make a new RecvLine that returns ".\n" for EOF or
  10.  *            a uucp envelope; that helps.
  11.  *    --- We also have the luxury of being able to back up and suck in raw
  12.  *            binhex/uudecode if the conversion fails
  13.  ************************************************************************/
  14. #pragma segment UUPCIn
  15. extern int Prr;
  16.  
  17. /************************************************************************
  18.  * GetUUPCMail - read mail from the named mailbox
  19.  ************************************************************************/
  20. short GetUUPCMail(Boolean quietly)
  21. {
  22. #pragma unused(quietly)
  23.     Str255 mailpath;
  24.     short err;
  25.     short anyErr = 0;
  26.     short gotSome = 0;
  27.     long oldPos;
  28.     TOCHandle inTocH;
  29.     Boolean foundOne;
  30.     short count;
  31.     
  32.     /*
  33.      * get the pathname of the maildrop
  34.      */
  35.     GetPref(mailpath,PREF_POP);
  36.     BlockMove(mailpath+2,mailpath+1,*mailpath-1);
  37.     (*mailpath)--;
  38.     Prr = 0;
  39.     
  40.     CurTrans = UUPCTrans;
  41.     
  42.     /*
  43.      * open it
  44.      */
  45.     if (err=FSOpen(mailpath,0,&DropRefN))
  46.         {FileSystemError(READ_MBOX,mailpath,err);goto done;}
  47.     
  48.     /*
  49.      * now, grab messages
  50.      */
  51.     for (foundOne=SkipToFromLine();foundOne;)
  52.     {
  53.         GetFPos(DropRefN,&oldPos);
  54.         Progress(NoChange,ComposeRString(mailpath,UUPC_COPY,gotSome+1));
  55.         BadBinHex = False;
  56.         BeginHexBin();
  57.         if (!AttachedFiles) AttachedFiles=NuHandle(0);
  58.         SetHandleBig(AttachedFiles,0);
  59.         count=POPMessageBody(0);
  60.         {extern int Prr; err = Prr;}
  61.         SetHandleBig(AttachedFiles,0);
  62.         EndHexBin();
  63.         SaveAbomination(nil,0);
  64.         if (!err && !BadBinHex) gotSome++;
  65.         anyErr |= err;
  66.         if (BadBinHex)
  67.         {
  68.             SetFPos(DropRefN,fsFromStart,oldPos);
  69.             NoAttachments = True;
  70.             inTocH = GetInTOC();
  71.             DeleteMessage(inTocH,(*inTocH)->count-1);
  72.             continue;
  73.         }
  74.         else
  75.         {
  76.             GetFPos(DropRefN,&oldPos);
  77.             NoAttachments = False;
  78.         }
  79.         foundOne = SkipToFromLine();
  80.     }
  81.     anyErr |= Prr;
  82. done:
  83.     if (DropRefN)
  84.     {
  85.         if (!PrefIsSet(PREF_DONT_DELETE) && 
  86.                 (!anyErr || ReallyDoAnAlert(CLEAR_DROP_ALRT,Normal)==1))
  87.             SetEOF(DropRefN,0);
  88.         FSClose(DropRefN);
  89.         DropRefN=0;
  90.     }
  91.     NoAttachments = False;
  92.     CurTrans = UseCTB ? CTBTrans : TCPTrans;
  93.     return(gotSome);
  94. }
  95.  
  96. /************************************************************************
  97.  * UUPCRecvLine - read a line at a time from the maildrop.    Returns ".\n"
  98.  * at the ends of messages.
  99.  ************************************************************************/
  100. int UUPCRecvLine(UPtr buffer, long *size)
  101. {
  102.     static Boolean wasFrom;
  103.     static Boolean wasNl=True;
  104.     short err;
  105.     IOParam iop;
  106.     
  107.     if (MiniEvents()) return(userCancelled);
  108.     if (!buffer) return(wasFrom);
  109.     wasFrom=False;
  110.     (*size)--;
  111.     
  112.     iop.ioCompletion=nil;
  113.     iop.ioRefNum=DropRefN;
  114.     iop.ioBuffer = buffer;
  115.     iop.ioReqCount = *size;
  116.     iop.ioPosMode = 1<<7 | ('\n'<<8);
  117.     iop.ioPosOffset = 0;
  118.     iop.ioActCount = 0;
  119.     err=PBRead(&iop,False);
  120.     if (iop.ioActCount) err=0;
  121.     *size = iop.ioActCount;
  122.     buffer[*size] = 0;
  123.     if (!DontTranslate && TransIn)
  124.         {Uptr cp; for(cp=buffer;cp<buffer+*size;cp++) *cp = TransIn[*cp];}
  125.     if (err && err!=eofErr)
  126.         {FileSystemError(READ_MBOX,"",err);}
  127.     if (!err || err==eofErr)
  128.     {
  129.         if (err || wasNl&&(wasFrom=IsFromLine(buffer)))
  130.         {
  131.             *size = 2;
  132.             buffer[0]='.'; buffer[1]='\n';
  133.         }
  134.         else if (wasNl && *buffer=='.')
  135.         {
  136.             BlockMove(buffer,buffer+1,*size);
  137.             (*size)++;
  138.             *buffer = '.';
  139.         }
  140.         buffer[*size] = 0;
  141.         err = noErr;
  142.     }
  143.     wasNl = err || buffer[*size-1]=='\n';
  144.     return(err);
  145. }
  146.  
  147. /************************************************************************
  148.  * SkipToFromLine - skip to the next envelope.    Also gives time to others,
  149.  * and keeps track of whether or not we last read a From line.
  150.  ************************************************************************/
  151. Boolean SkipToFromLine(void)
  152. {
  153.     Str255 buffer;
  154.     long eof, atNow, size;
  155.     short err;
  156.     EventRecord event;
  157.     
  158.     if (WNE(everyEvent,&event,0))
  159.     {
  160.         (void) MiniMainLoop(&event);
  161.         if (CommandPeriod) {Prr = userCancelled; return(False);}
  162.     }
  163.     if ((err=GetEOF(DropRefN,&eof)) || (err=GetFPos(DropRefN,&atNow)))
  164.     {
  165.         FileSystemError(READ_MBOX,GetPref(buffer,PREF_POP),err);
  166.         Prr = err;
  167.         return(False);
  168.     }
  169.     if (eof) Progress((atNow*100)/eof,nil);
  170.     if (!eof || atNow==eof) return(False);
  171.     if (RecvLine(nil,nil)) return(True);
  172.     do
  173.     {
  174.         size = sizeof(buffer);
  175.         if (err=RecvLine(buffer,&size))
  176.         {
  177.             FileSystemError(READ_MBOX,GetPref(buffer,PREF_POP),err);
  178.             Prr = err;
  179.             return(False);
  180.         }
  181.     }
  182.     while (size!=2 || *buffer!='.');
  183.     if (eof) Progress((atNow*100)/eof,nil);
  184.     
  185.     return(True);
  186. }
  187.  
  188. #pragma segment UUPCOut
  189. /************************************************************************
  190.  * Ok; sending mail is more complicated, but it's easier to do
  191.  * SMTP server item has to have the following info, ! separated:
  192.  *    - the name of our mac
  193.  *    - the name of the remote system (optional, ignored if present)
  194.  *    - the path to the spool directory
  195.  *    - our user name
  196.  *    - our current sequence number
  197.  *    ie, !mymac!relay!spoolvol:spooldir:!username!0000
  198.  *    - We generate a sequence number, 4 digits (####)
  199.  *    - We deposit the mail in D.relay0####, newline-separated
  200.  *    - In D.mymac0####, we put commands for the UUCP system, newline-separated
  201.  *    --- U username mymac                ; this is us
  202.  *    --- F D.mymac0####                    ; this is the mail file, on the remote system
  203.  *    --- I D.mymac0####                    ; and we're using it for input
  204.  *    --- C rmail <recip-list>        ; the command; rmail and recipients as args
  205.  *
  206.  *    By declaring our own SendTrans, we actually can use TransmitMessage
  207.  *    from sendmail.c, which is tres nice.
  208.  *
  209.  *    There are some race conditions in creating the files.  So what?
  210.  ************************************************************************/
  211.  
  212. typedef struct
  213. {
  214.     Str255 spoolPath;
  215.     Str15 myMac;
  216.     unsigned char relay[9];
  217.     Str15 userName;
  218.     short sequence;
  219.     short refNs[2];
  220.     Str255 files[2];
  221.     Str31 fileNames[2];
  222.     short oldSeq;
  223.     MessHandle messH;
  224. } UUXBlock,*UUXPtr,**UUXHandle;
  225. UUXHandle UUX;
  226. #define SpoolPath (*UUX)->spoolPath
  227. #define MyMac (*UUX)->myMac
  228. #define Relay (*UUX)->relay
  229. #define UserName (*UUX)->userName
  230. #define Sequence (*UUX)->sequence
  231. #define MailRefN (*UUX)->refNs[0]
  232. #define XRefN (*UUX)->refNs[1]
  233. #define MailFile (*UUX)->files[0]
  234. #define XFile (*UUX)->files[1]
  235. #define Dmymac (*UUX)->fileNames[0]
  236. #define Xmymac (*UUX)->fileNames[1]
  237. #define OldSeq (*UUX)->oldSeq
  238. #define MessH (*UUX)->messH
  239.  
  240. void UUPCGenFilenames(void);
  241. Boolean UUPCBadFilenames(void);
  242. int UUPCMakeFiles(void);
  243. void UUPCKillFiles(void);
  244. void UUPCCloseFiles(void);
  245. int UUPCOpenFiles(void);
  246. int UUPCWriteXFile(void);
  247. int UUPCWriteMailFile(void);
  248. void UUPCGetNewline(UPtr newline,UPtr buffer);
  249. /************************************************************************
  250.  * UUPCPrime - get ready
  251.  ************************************************************************/
  252. int UUPCPrime(UPtr server)
  253. {
  254.     UPtr bangs[6];    /* these will point to exclams in the server text */
  255.     UPtr *bang;
  256.     short err;
  257.     short seq;
  258.     
  259.     /*
  260.      * count the bangs, shall we?
  261.      */
  262.     WriteZero(bangs,sizeof(bangs));
  263.     bangs[0] = server+1;    /* first one */
  264.     for (bang=bangs+1;bang<bangs+sizeof(bangs)/sizeof(UPtr);bang++)
  265.     {
  266.         *bang = strchr(bang[-1]+1,'!');    /* look for next exclam */
  267.         if (!*bang) break;
  268.     }
  269.     
  270.     if (!bangs[3]) {WarnUser(UUPC_WRONG_SMTP,0);return(1);}    /* not enough */
  271.     if (!bangs[4])
  272.     {
  273.         /* relay not included; insert a pretend relay */
  274.         BlockMove(bangs+1,bangs+2,3*sizeof(UPtr));
  275.     }
  276.     bangs[5] = server+*server+1;    /* end of the string */
  277.  
  278.     /*
  279.      * allocate some space
  280.      */
  281.     if (!UUX) UUX=NewZH(UUXBlock);
  282.     if (!UUX) {WarnUser(MEM_ERR,err=MemError());return(err);}
  283.     
  284.     /*
  285.      * copy values into it
  286.      */
  287. #define MOVE(to,b1,b2) do{ \
  288.     *to=MIN(sizeof(to)-2,bangs[b2]-bangs[b1]-1); to[*to+1]=0; \
  289.     BlockMove(bangs[b1]+1,to+1,*to); } while (0)
  290.     
  291.     MOVE(MyMac,0,1);
  292.     MOVE(SpoolPath,2,3);
  293.     MOVE(UserName,3,4);
  294.     seq = atoi(bangs[4]+1);
  295.     Sequence = seq;
  296.     
  297.     CurTrans = UUPCTrans;
  298.     
  299.     return(noErr);
  300. }
  301.  
  302. /************************************************************************
  303.  * UUPCDry - put away the toys
  304.  ************************************************************************/
  305. void UUPCDry(void)
  306. {
  307.     if (UUX)
  308.     {
  309.         if (*UUX)
  310.         {
  311.             if (Sequence!=OldSeq)
  312.             {
  313.                 Str255 smtp;
  314.                 GetPref(smtp,PREF_SMTP);
  315.                 if (*smtp>4)
  316.                 {
  317.                     UPtr cp = smtp+*smtp;
  318.                     short n=4;
  319.                     while (n--)
  320.                     {
  321.                         *cp-- = Sequence%10+'0';
  322.                         Sequence /= 10;
  323.                     }
  324.                 }
  325.                 ChangeStrn(PREF_STRN,PREF_SMTP,smtp);
  326.             }
  327.         }
  328.         ZapHandle(UUX);
  329.     }
  330.     CurTrans = UseCTB ? CTBTrans : TCPTrans;
  331. }
  332.  
  333. /************************************************************************
  334.  * UUPCSendMessage - the hard work goes here
  335.  ************************************************************************/
  336. int UUPCSendMessage(TOCHandle tocH,short sumNum)
  337. {
  338.     short err;
  339.     MessHandle messH;
  340.     
  341.     /*
  342.      * grab the message
  343.      */
  344.     if (!(messH=SaveB4Send(tocH,sumNum))) return(1);
  345.     MessH = messH;
  346.  
  347.     /*
  348.      * generate some unique filenames in the spool directory
  349.      */
  350.     do {UUPCGenFilenames();} while (UUPCBadFilenames());
  351.     err = UUPCMakeFiles();
  352.     if (!err)
  353.     {
  354.         err = UUPCOpenFiles();
  355.         if (!err)
  356.         {
  357.             err = UUPCWriteXFile();
  358.             if (!err) err = UUPCWriteMailFile();
  359.         }
  360.     }
  361.  
  362.     UUPCCloseFiles();
  363.     if (err) UUPCKillFiles();
  364.     else TimeStamp(tocH,sumNum,GMTDateTime(),ZoneSecs());
  365.     return(err);
  366. }
  367.  
  368. /************************************************************************
  369.  * UUPCGenFilenames - make the filenames
  370.  ************************************************************************/
  371. void UUPCGenFilenames(void)
  372. {
  373.     Str15 seq;
  374.     int n;
  375.     Str255 scratch;
  376.     Str15 mymacShort;
  377.     
  378.     PCopy(mymacShort,MyMac);
  379.     *mymacShort=MIN(7,*mymacShort);
  380.     
  381.     n = ++Sequence;
  382.     seq[0] = 4;
  383.     seq[4] = n%10+'0'; n/=10;
  384.     seq[3] = n%10+'0'; n/=10;
  385.     seq[2] = n%10+'0'; n/=10;
  386.     seq[1] = n%10+'0';
  387.     ComposeRString(scratch,UUPC_DMYMAC,mymacShort,seq); PCopy(Dmymac,scratch);
  388.     ComposeRString(scratch,UUPC_XMYMAC,mymacShort,seq); PCopy(Xmymac,scratch);
  389.     PCopy(MailFile,SpoolPath); PCat(MailFile,Dmymac);
  390.     PCopy(XFile,SpoolPath); PCat(XFile,Xmymac);
  391. }
  392.  
  393. /************************************************************************
  394.  * UUPCBadFilenames - check that our files don't already exist
  395.  ************************************************************************/
  396. Boolean UUPCBadFilenames(void)
  397. {
  398.     Str255 scratch;
  399.     short i;
  400.     HFileInfo hfi;
  401.     
  402.     for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
  403.     {
  404.         PCopy(scratch,(*UUX)->files[i]);
  405.         if (!HGetFileInfo(0,0,scratch,&hfi)) return(True);
  406.     }
  407.     return(False);
  408. }
  409.  
  410. /************************************************************************
  411.  * UUPCMakeFiles - create our files
  412.  ************************************************************************/
  413. int UUPCMakeFiles(void)
  414. {
  415.     Str255 scratch;
  416.     short i,err;
  417.     long creator;
  418.     
  419.     GetPref(scratch,PREF_CREATOR);
  420.     if (*scratch!=4) GetRString(scratch,TEXT_CREATOR);
  421.     BlockMove(scratch+1,&creator,4);
  422.     
  423.     for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
  424.     {
  425.         PCopy(scratch,(*UUX)->files[i]);
  426.         if (err=HCreate(0,0,scratch,creator,'TEXT'))
  427.             return(FileSystemError(TEXT_WRITE,scratch,err));
  428.     }
  429.     return(False);
  430. }
  431.  
  432. /************************************************************************
  433.  * UUPCCloseFiles - close our files
  434.  ************************************************************************/
  435. void UUPCCloseFiles(void)
  436. {
  437.     short i;
  438.     for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
  439.         if ((*UUX)->refNs[i]) (void) FSClose((*UUX)->refNs[i]);
  440. }
  441.  
  442. /************************************************************************
  443.  * UUPCKillFiles - destroy our files
  444.  ************************************************************************/
  445. void UUPCKillFiles(void)
  446. {
  447.     Str255 scratch;
  448.     short i;
  449.     for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
  450.     {
  451.         PCopy(scratch,(*UUX)->files[i]);
  452.         (void) HDelete(0,0,scratch);
  453.     }
  454.     Sequence--;
  455. }
  456.  
  457. /************************************************************************
  458.  * UUPCOpenFiles - open our files
  459.  ************************************************************************/
  460. int UUPCOpenFiles(void)
  461. {
  462.     Str255 scratch;
  463.     short i,err,refN;
  464.     for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
  465.     {
  466.         PCopy(scratch,(*UUX)->files[i]);
  467.         if (err=FSOpen(scratch,0,&refN))
  468.             return(FileSystemError(TEXT_WRITE,scratch,err));
  469.         (*UUX)->refNs[i] = refN;
  470.     }
  471.     return(0);
  472. }
  473.  
  474. /************************************************************************
  475.  * UUPCWriteXFile - write the file to send to the other side for execution
  476.  ************************************************************************/
  477. int UUPCWriteXFile(void)
  478. {
  479.     short err;
  480.     Str255 buffer;
  481.     Str15 newline;
  482.     
  483.     LDRef(UUX);
  484.     
  485.     ComposeRString(buffer,UUPC_U_CMD,UserName,MyMac);
  486.     err = FSWriteP(XRefN,buffer);
  487.     
  488.     if (!err)
  489.     {
  490.         UUPCGetNewline(newline,buffer);
  491.         
  492.         ComposeRString(buffer,UUPC_F_CMD,Dmymac);
  493.         err = FSWriteP(XRefN,buffer);
  494.         
  495.         if (!err)
  496.         {
  497.             ComposeRString(buffer,UUPC_I_CMD,Dmymac);
  498.             err = FSWriteP(XRefN,buffer);
  499.             
  500.             if (!err)
  501.             {
  502.                 UL(UUX);
  503.                 GetRString(buffer,UUPC_C_CMD);
  504.                 err = FSWriteP(XRefN,buffer);
  505.                 
  506.                 if (!err) err=DoRcptTos(MessH,False);
  507.                 if (!err) err=FSWriteP(XRefN,newline);
  508.             }
  509.         }
  510.     }
  511.     
  512.     if (err) FileSystemError(TEXT_WRITE,XFile,err);
  513.     UL(UUX);
  514.     return(err);
  515. }
  516.  
  517. /************************************************************************
  518.  * UUPCWriteMailFile - get the message into the file
  519.  ************************************************************************/
  520. int UUPCWriteMailFile(void)
  521. {
  522.     MSumType sum;
  523.     Str255 envelope;
  524.     short len;
  525.     Str15 oldNewLine;
  526.     short err;
  527.     
  528.     PCopy(sum.from,UserName);
  529.     *envelope = SumToFrom(&sum,envelope+1);
  530.     
  531.     LDRef(UUX);
  532.     ComposeRString(envelope+*envelope,UUPC_REMOTE,MyMac);
  533.     UL(UUX);
  534.     
  535.     len = *envelope;
  536.     *envelope += envelope[len];
  537.     envelope[len] = ' ';
  538.     if (err=FSWriteP(MailRefN,envelope))
  539.     {
  540.         PCopy(envelope,MailFile);
  541.         FileSystemError(TEXT_WRITE,envelope,err);
  542.         return(err);
  543.     }
  544.  
  545.     PCopy(oldNewLine,NewLine);
  546.     UUPCGetNewline(NewLine,envelope);
  547.     err = TransmitMessage(MessH,False);
  548.     PCopy(NewLine,oldNewLine);
  549.     return(err);
  550. }
  551.  
  552. /************************************************************************
  553.  * UUCPWriteAddr - write an address to the X file
  554.  ************************************************************************/
  555. int UUPCWriteAddr(UPtr addr)
  556. {
  557.     Str255 buffer;
  558.     short err;
  559.     
  560.     *buffer = 1;
  561.     buffer[1] = ' ';
  562.     PCat(buffer,addr);
  563.     if (err=FSWriteP(XRefN,buffer))
  564.     {
  565.         PCopy(buffer,XFile);
  566.         FileSystemError(TEXT_WRITE,buffer,err);
  567.     }
  568.     return(err ? 500 : 0);
  569. }
  570.  
  571. /************************************************************************
  572.  * UUPCGetNewline - what's this guy using for a newline?
  573.  ************************************************************************/
  574. void UUPCGetNewline(UPtr newline,UPtr buffer)
  575. {
  576.     UPtr bp;
  577.     for (bp=buffer+*buffer;bp[-1]<' ';bp--);
  578.     *newline = (buffer+*buffer)-bp+1;
  579.     BlockMove(bp,newline+1,*newline);
  580. }
  581.  
  582. /************************************************************************
  583.  * UUPCSendTrans - sendtrans to a file
  584.  ************************************************************************/
  585. int UUPCSendTrans(short count, UPtr text,long size, ...)
  586. {
  587.     long bSize;
  588.     short err;
  589.     
  590.     if (size==0) return(noErr);     /* allow vacuous sends */
  591.     if (MiniEvents()) return(userCancelled);
  592.     
  593.     if (!DontTranslate && TransOut)
  594.         {Uptr cp; for(cp=text;cp<text+size;cp++) *cp = TransOut[*cp];}
  595.     bSize = size;
  596.     if (err=FSWrite(MailRefN,&bSize,text))
  597.         return(FileSystemError(TEXT_WRITE,MailFile,err));
  598.     if (--count>0)
  599.     {
  600.         Uptr buffer;
  601.         va_list extra_buffers;
  602.         va_start(extra_buffers,size);
  603.         while (count--)
  604.         {
  605.             buffer = va_arg(extra_buffers,UPtr);
  606.             bSize = va_arg(extra_buffers,int);
  607.             if (UUPCSendTrans(1,buffer,bSize)) break;
  608.         }
  609.         va_end(extra_buffers);
  610.     }
  611.     return(err);
  612. }
  613.